/*
 * Created on 24.07.2006 by leck
 *
 */
package de.devisnik.shifting.eidle;

import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;

import de.devisnik.eidle.picture.ImageUtils;
import de.devisnik.eidle.util.AbstractScreen;
import de.devisnik.shifting.IGame;
import de.devisnik.shifting.impl.IPuzzleCanvasListener;
import de.devisnik.shifting.impl.PuzzleCanvas;

public class ShiftingScreen extends AbstractScreen {

	private PuzzleCanvas itsCanvas;
	private Image itsInnerImage;
	private Composite itsComposite;
	private final IGame game;
	private IPuzzleCanvasListener puzzleCanvasListener;
	private final int shiftingDelay;
	private final int showResultTime;
	private final ImageDescriptor imageDescriptor;

	public ShiftingScreen(final IGame game, final int shiftingDelay,
			final int showResultTime, final ImageDescriptor imageDescriptor) {
		super("Display-Shifting");
		this.game = game;
		this.shiftingDelay = shiftingDelay;
		this.showResultTime = showResultTime;
		this.imageDescriptor = imageDescriptor;
	}

	private Image createImage(final Composite parent) {
		return imageDescriptor.createImage();
	}

	public void createControl(final Composite parentShell) {
		initPuzzleCanvas(parentShell);
	}

	private Image makeInnerImage(final Composite parent) {
		final Image image = createImage(parent);
		final Point gameSize = game.getPuzzle().getSize();
		final int borderX = image.getBounds().width % gameSize.x;
		final int borderY = image.getBounds().height % gameSize.y;
		final Image innerImage = ImageUtils.getInnerImage(parent.getDisplay(),
				image, borderX, borderY);
		image.dispose();
		return innerImage;

	}

	private void initPuzzleCanvas(final Composite parent) {

		game.init();
		itsInnerImage = makeInnerImage(parent);

		itsComposite = new Composite(parent, SWT.NO_REDRAW_RESIZE);
		itsComposite.addControlListener(new ControlAdapter() {

			public void controlResized(final ControlEvent e) {
				final Point gameSize = game.getPuzzle().getSize();
				final int borderX = parent.getBounds().width % gameSize.x;
				final int borderY = parent.getBounds().height % gameSize.y;
				itsCanvas.setLocation(borderX / 2, borderY / 2);
				itsCanvas.setSize(parent.getBounds().width - borderX, parent
						.getBounds().height
						- borderY);
			}
		});
		itsCanvas = new PuzzleCanvas(game.getPuzzle(), itsInnerImage,
				shiftingDelay, itsComposite, SWT.NONE);

		game.executeNextMove();
		puzzleCanvasListener = new IPuzzleCanvasListener() {

			public void doneShifting() {
				if (!game.isDone()) {
					game.executeNextMove();
				} else {
					itsCanvas.getDisplay().timerExec(showResultTime,
							new Runnable() {

								public void run() {
									fireScreenDone();
								}
							});
				}
			}
		};
		itsCanvas.addListener(puzzleCanvasListener);
	}

	public void disposeControl() {
		if (itsComposite != null) {
			itsCanvas.removeListener(puzzleCanvasListener);
			itsComposite.dispose();
		}
		if (itsInnerImage != null) {
			itsInnerImage.dispose();
		}
	}

	public void dispose() {
	}

	public void setFocus() {
		if (itsCanvas != null) {
			itsCanvas.setFocus();
		}
	}

}
